package com.guoxin.concurrentprogramming.chapter4.parallel;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Administrator
 */
public class ParallelSearch {
    private static int threadNum = 2;
    private static ExecutorService service = Executors.newCachedThreadPool();

    private static AtomicInteger result = new AtomicInteger(-1);
    private static int[] arr;

    private static int search(int searchValue, int begin, int end) {
        for (int i = begin; i < end; i++) {
            if (result.get() > 0) {
                return result.get();
            }
            if (arr[i] == searchValue) {
                if (!result.compareAndSet(-1, i)) {
                    return result.get();
                }
                return i;
            }
        }
        return -1;
    }

    private static class SearchTask implements Callable<Integer> {
        int begin, end, searchValue;

        SearchTask(int begin, int end, int searchValue) {
            this.begin = begin;
            this.end = end;
            this.searchValue = searchValue;
        }

        @Override
        public Integer call() throws Exception {
            return search(searchValue, begin, end);
        }
    }

    public static int pSearch(int searchValue) throws ExecutionException, InterruptedException {
        int subArraySize = arr.length / threadNum;
        List<Future<Integer>> re = new ArrayList<>();
        for (int i = 0; i < arr.length; i = i + subArraySize) {
            int end = i + searchValue;
            if (end > arr.length) {
                end = arr.length;
            }
            re.add(service.submit(new SearchTask(i, end, searchValue)));
        }
        for (Future<Integer> f : re) {
            if (f.get() >= 0) {
                return f.get();
            }
        }
        return -1;
    }
}
